package weifei.live.simulation.controller;


import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import weifei.live.simulation.entity.Avatar;
import weifei.live.simulation.entity.User;
import weifei.live.simulation.entity.UserFollow;
import weifei.live.simulation.entity.UserFriend;
import weifei.live.simulation.entity.dto.UserDTO;
import weifei.live.simulation.service.UserService;
import weifei.web.Result;

import java.util.Date;


@RestController
@RequestMapping("/user")
public class UserController
{
    @Autowired
    private UserService userService;


    @Autowired
    private User dao_user;
    @Autowired
    private UserFollow dao_user_follow;
    @Autowired
    private UserFriend dao_user_friend;



    @PostMapping("/register")
    @Transactional
    public Result register(@Valid @RequestBody User user)
    {
        if (user.getNickname() == null)
            user.setNickname(user.getUsername());

        User u = new User(user.getNickname(), user.getUsername(), user.getPassword());

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        qw_user.eq(User.Column.Username.getName(), user.getUsername());

        User original_user = this.dao_user.selectOne(qw_user);
        if (original_user != null)
            return Result.failed("注册失败，用户名已被使用");
        if (!u.insert())
            return Result.exception("注册失败，数据库出错");

        var new_user = this.dao_user.selectOne(qw_user);
        if (!new UserFriend(new_user.getId(), new_user.getId()).insert())
            throw new RuntimeException("将自己添加为朋友失败");

        return Result.success("注册成功");
    }


    @PostMapping("/login")
    public Result login(
            HttpSession session,
            @Valid @RequestBody User user
    )
    {
        QueryWrapper<User> qw_user = new QueryWrapper<>();
        qw_user.eq(User.Column.Username.getName(), user.getUsername());
        User target = this.dao_user.selectOne(qw_user);

        if (target == null)
        {
            qw_user.clear();
            qw_user.eq(User.Column.Phone.getName(), user.getUsername());// 用户填账号的时候都是填同一个框，所以getUsername可能是手机号
            target = this.dao_user.selectOne(qw_user);
            if (target == null)// 手机号也查不到就登录失败
                return Result.failed("用户不存在");
        }

        if (!target.getPassword().equals(user.getPassword()))
            return Result.failed("登录失败，密码错误");

        target.setLastLoginTime(new Date());
        // target.setState(User.State.Online);
        if (!target.updateById())
            return Result.exception("登录失败，数据库出错");
        // session.setAttribute(SessionAttribute.User.getName(), target);

        String token = JWT.create()
                .withIssuedAt(new Date())
                .withExpiresAt(new Date(System.currentTimeMillis() + 86400000))   // 一天过期
                .withClaim("userID", target.getId())
                .sign(Algorithm.HMAC256(target.getPassword()));     //使用HMAC算法，password作为密钥加密

        return Result.success("登录成功", token);
    }



    @GetMapping("/getUserByID")
    @PostMapping("/getUserByID")
    public Result getUserByID(@RequestParam("id") Integer id)
    {
        if (id == null)
            return Result.exception("参数错误");

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        qw_user.eq(User.Column.ID.getName(), id);
        User user = this.dao_user.selectOne(qw_user);
        if (user == null)
            return Result.failed("用户不存在");
        UserDTO dto = new UserDTO(user);
        return Result.success("获取成功", dto);
    }



    @GetMapping("/getUserAvatarContentByUserID")
    @PostMapping("/getUserAvatarContentByUserID")
    public Result getUserAvatarContentByUserID(@RequestParam("id") Integer userId)
    {
        if (userId == null)
            return Result.exception("参数错误");

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        qw_user.eq(User.Column.ID.getName(), userId);
        User user = this.dao_user.selectOne(qw_user);
        if (user == null)
            return Result.failed("用户不存在");
        return Result.success("获取成功", user.getAvatarBase64());
    }



    /** 查某个用户关注了多少人 */
    @GetMapping("/getFollowCountByUserID")
    @PostMapping("/getFollowCountByUserID")
    public Result getFollowCountByUserID(@RequestParam("id") Integer userId)
    {
        if (userId == null)
            return Result.exception("参数错误");

        QueryWrapper<UserFollow> qw_follow = new QueryWrapper<>();
        qw_follow.eq(UserFollow.Column.UserID.getName(), userId);
        long count = this.dao_user_follow.selectCount(qw_follow);
        return Result.success("获取成功", count);
    }


    /** 查某个用户被多少人关注 */
    @GetMapping("/getFansCountByUserID")
    @PostMapping("/getFansCountByUserID")
    public Result getFansCountByUserID(@RequestParam("id") Integer userId)
    {
        if (userId == null)
            return Result.exception("参数错误");

        QueryWrapper<UserFollow> qw_follow = new QueryWrapper<>();
        qw_follow.eq(UserFollow.Column.FollowID.getName(), userId);
        long count = this.dao_user_follow.selectCount(qw_follow);
        return Result.success("获取成功", count);
    }



    /** 此处有 登录拦截 */
    @PostMapping("/bindPhoneNumber")
    public Result bindPhoneNumber()
    {
        return Result.failed("手机号绑定失败");
    }


    @GetMapping("/getUserSelf")
    @PostMapping("/getUserSelf")
    public Result getUserSelf(HttpServletRequest request)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);
        return this.getUserByID(user_id);
    }


    @PostMapping("/uploadAvatar")
    @Transactional
    public Result uploadAvatar(HttpServletRequest request, @RequestParam("content") String content)
    {
        var token = request.getHeader("token");
        User user = this.userService.getUserByToken(token);

        var a = new Avatar(content);
        if (!a.insert())
            return Result.failed("头像上传失败，数据库出错");

        var qw = new QueryWrapper<Avatar>();
        qw.eq(Avatar.Column.Content.name(), a.getContent());
        var a2 = a.selectOne(qw);
        user.setAvatarId(a2.getId());
        if (!user.updateById())
            throw new RuntimeException("用户" + user.getId() + " 头像ID修改失败");
        return Result.success("头像上传成功", a2.getId());
    }


    @PostMapping("/addFriend")
    public Result addFriend(HttpServletRequest request, @RequestParam("id") int friendId)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);

        if (friendId == user_id)
            return Result.failed("不能将自己添加为朋友");

        this.dao_user.setId(friendId);
        var target = this.dao_user.selectById();
        if (target == null)
            return Result.failed("添加的用户不存在");

        var f = new UserFriend(user_id, friendId);

        QueryWrapper<UserFriend> qw_friend = new QueryWrapper<>();
        qw_friend.eq(UserFriend.Column.UserID.getName(), user_id);
        qw_friend.eq(UserFriend.Column.FriendID.getName(), friendId);
        var friend_data = this.dao_user_friend.selectOne(qw_friend);
        if (friend_data != null)// 已经是朋友则添加失败
            return Result.failed("对方已经是你的朋友了");

        if (!f.insert())
            return Result.exception("添加失败，数据库出错");
        return Result.success("添加成功");
    }


    @PostMapping("/deleteFriend")
    public Result deleteFriend(HttpServletRequest request, @RequestParam("id") int friendId)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);

        QueryWrapper<UserFriend> qw_friend = new QueryWrapper<>();
        qw_friend.eq(UserFriend.Column.UserID.getName(), user_id);
        qw_friend.eq(UserFriend.Column.FriendID.getName(), friendId);
        var friend_data = this.dao_user_friend.selectOne(qw_friend);
        if (friend_data == null)
            return Result.failed("对方不是你的朋友");

        if (!this.dao_user_friend.delete(qw_friend))
            return Result.exception("删除失败，数据库出错");
        return Result.success("删除成功");
    }


    @GetMapping("/getFriendArray")
    @PostMapping("/getFriendArray")
    public Result getFriendArray(HttpServletRequest request)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);

        QueryWrapper<UserFriend> qw_friend = new QueryWrapper<>();
        qw_friend.eq(UserFriend.Column.UserID.getName(), user_id);
        var list = this.dao_user_friend.selectList(qw_friend);

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        var dto_array = new UserDTO[list.size()];
        for(int i = 0; i < list.size(); i++)
        {
            qw_user.clear();
            qw_user.eq(User.Column.ID.getName(), list.get(i).getFriendId());
            var friend = new User().selectOne(qw_user);
            dto_array[i] = new UserDTO(friend);
        }

        return Result.success("获取成功", dto_array);
    }


    @PostMapping("/follow")
    public Result follow(HttpServletRequest request, @RequestParam("id") int followId)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        qw_user.eq(User.Column.ID.getName(), followId);
        User target = new User().selectOne(qw_user);
        if (target == null)
            return Result.failed("关注的用户不存在");


        UserFollow f = new UserFollow(user_id, followId);

        QueryWrapper<UserFollow> qw_follow = new QueryWrapper<>();
        qw_follow.eq(UserFollow.Column.UserID.getName(), user_id);
        qw_follow.eq(UserFollow.Column.FollowID.getName(), followId);

        var follow_data = this.dao_user_follow.selectOne(qw_follow);
        if (follow_data != null)// 有关注的数据则取关
        {
            if (!this.dao_user_follow.delete(qw_follow))
                return Result.exception("取消关注失败，数据库出错");
            return Result.success("取消关注成功");
        }

        // 没有关注的数据则添加关注数据
        if (!f.insert())
            return Result.exception("关注失败，数据库出错");
        return Result.success("关注成功");
    }


    @GetMapping("/getFollowArray")
    @PostMapping("/getFollowArray")
    public Result getFollowArray(HttpServletRequest request)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);

        QueryWrapper<UserFollow> qw_follow = new QueryWrapper<>();
        qw_follow.eq(UserFollow.Column.UserID.getName(), user_id);
        var list = this.dao_user_follow.selectList(qw_follow);

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        var dto_array = new UserDTO[list.size()];
        for(int i = 0; i < list.size(); i++)
        {
            qw_user.clear();
            qw_user.eq(User.Column.ID.getName(), list.get(i).getFollowId());
            var follower = new User().selectOne(qw_user);
            dto_array[i] = new UserDTO(follower);
        }

        return Result.success("获取成功", dto_array);
    }


    @GetMapping("/getFansArray")
    @PostMapping("/getFansArray")
    public Result getFansArray(HttpServletRequest request)
    {
        var token = request.getHeader("token");
        var user_id = this.userService.getUserIDByToken(token);

        QueryWrapper<UserFollow> qw_follow = new QueryWrapper<>();
        qw_follow.eq(UserFollow.Column.FollowID.getName(), user_id);
        var list = this.dao_user_follow.selectList(qw_follow);

        QueryWrapper<User> qw_user = new QueryWrapper<>();
        var dto_array = new UserDTO[list.size()];
        for(int i = 0; i < list.size(); i++)
        {
            qw_user.clear();
            qw_user.eq(User.Column.ID.getName(), list.get(i).getUserId());
            var fans = new User().selectOne(qw_user);
            dto_array[i] = new UserDTO(fans);
        }

        return Result.success("获取成功", dto_array);
    }

}








